home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / asy.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  7KB  |  323 lines

  1. /* Generic serial line interface routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4.  /* Mods by G1EMM */
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "config.h"
  8. #include "proc.h"
  9. #include "iface.h"
  10. #include "netuser.h"
  11. #include "slhc.h"
  12. #ifdef UNIX
  13. #include "unixasy.h"
  14. #else
  15. #include "i8250.h"
  16. #endif
  17. #include "asy.h"
  18. #include "ax25.h"
  19. #include "kiss.h"
  20. #include "pktdrvr.h"
  21. #include "ppp.h"
  22. #include "slip.h"
  23. #include "nrs.h"
  24. #include "commands.h"
  25. #include "mbuf.h"
  26.  
  27. static int asy_detach __ARGS((struct iface *ifp));
  28.  
  29.  
  30. /* Attach a serial interface to the system
  31.  * argv[0]: hardware type, must be "asy"
  32.  * argv[1]: I/O address, e.g., "0x3f8"
  33.  * argv[2]: vector, e.g., "4"
  34.  * argv[3]: mode, may be:
  35.  *        "slip" (point-to-point SLIP)
  36.  *        "ax25" (AX.25 frame format in SLIP for raw TNC)
  37.  *        "nrs" (NET/ROM format serial protocol)
  38.  *        "ppp" (Point-to-Point Protocol, RFC1171, RFC1172)
  39.  * argv[4]: interface label, e.g., "sl0"
  40.  * argv[5]: receiver ring buffer size in bytes
  41.  * argv[6]: maximum transmission unit, bytes
  42.  * argv[7]: interface speed, e.g, "9600"
  43.  * argv[8]: optional flags,
  44.  *        'v' for Van Jacobson TCP header compression (SLIP only,
  45.  *            use ppp command for VJ compression with PPP);
  46.  *      'f' for forced use of the 16550 fifo's - WG7J
  47.  *      'nn' to set 16550 trigger level - WG7J
  48.  */
  49. int
  50. asy_attach(argc,argv,p)
  51. int argc;
  52. char *argv[];
  53. void *p;
  54. {
  55.     register struct iface *ifp;
  56.     struct asy *asyp;
  57.     char *ifn;
  58.     int dev;
  59.     int xdev;
  60.     int trigchar = -1;
  61.     char monitor = FALSE;
  62.     int triglevel = 0;
  63.     int force = 0;
  64.     char *cp;
  65. #if    defined(SLIP) || defined(AX25)
  66.     struct slip *sp;
  67. #endif
  68. #ifdef    NRS
  69.     struct nrs *np;
  70. #endif
  71.  
  72.     if(if_lookup(argv[4]) != NULLIF){
  73.         tprintf(Existingiface,argv[4]);
  74.         return -1;
  75.     }
  76.     /* Find unused asy control block */
  77.     for(dev=0;dev < ASY_MAX;dev++){
  78.         asyp = &Asy[dev];
  79.         if(asyp->iface == NULLIF)
  80.             break;
  81.     }
  82.     if(dev >= ASY_MAX){
  83.         tprintf("Too many async controllers\n");
  84.         return -1;
  85.     }
  86.  
  87.     /* Create interface structure and fill in details */
  88.     ifp = (struct iface *)callocw(1,sizeof(struct iface));
  89.     ifp->addr = Ip_addr;
  90.     ifp->name = strdup(argv[4]);
  91.     ifp->mtu = atoi(argv[6]);
  92.     ifp->dev = dev;
  93.     ifp->stop = asy_detach;
  94.  
  95.     /*Check for forced 16550 fifo usage - WG7J */
  96.     if((argc > 8) && ((cp = strchr(argv[8],'f')) != NULLCHAR)) {
  97.         force = 1;
  98.         if((triglevel = atoi(++cp)) == 0)   /* is there an additional arg ? */
  99.             if(argc > 9)
  100.                 triglevel = atoi(argv[9]);
  101.     }
  102.  
  103.  
  104. #ifdef    SLIP
  105.     if(stricmp(argv[3],"SLIP") == 0) {
  106.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  107.             sp = &Slip[xdev];
  108.             if(sp->iface == NULLIF)
  109.                 break;
  110.         }
  111.         if(xdev >= SLIP_MAX) {
  112.             tprintf("Too many slip devices\n");
  113.             free(ifp->name);
  114.             free((char *)ifp);
  115.             return -1;
  116.         }
  117.         setencap(ifp,"SLIP");
  118.         ifp->ioctl = asy_ioctl;
  119.         ifp->raw = slip_raw;
  120.         ifp->show = slip_status;
  121.         ifp->flags = 0;
  122.         ifp->xdev = xdev;
  123.  
  124.         sp->iface = ifp;
  125.         sp->send = asy_send;
  126.         sp->get = get_asy;
  127.         sp->type = CL_SERIAL_LINE;
  128.         trigchar = FR_END;
  129. #ifdef VJCOMPRESS
  130.         if((argc > 8) && (strchr(argv[8],'v') != NULLCHAR)) {
  131.             sp->escaped |= SLIP_VJCOMPR;
  132.             sp->slcomp = slhc_init(16,16);
  133.         }
  134. #else
  135.         sp->slcomp = NULL;
  136. #endif    /* VJCOMPRESS */
  137.         ifp->rxproc = newproc( ifn = if_name( ifp, " rx" ),
  138.             256,asy_rx,xdev,NULL,NULL,0);
  139.         free(ifn);
  140.     } else
  141. #endif
  142. #ifdef    AX25
  143.     if(stricmp(argv[3],"AX25") == 0) {
  144.         /* Set up a SLIP link to use AX.25 */
  145.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  146.             sp = &Slip[xdev];
  147.             if(sp->iface == NULLIF)
  148.                 break;
  149.         }
  150.         if(xdev >= SLIP_MAX) {
  151.             tprintf("Too many ax25 devices\n");
  152.             free(ifp->name);
  153.             free((char *)ifp);
  154.             return -1;
  155.         }
  156.         setencap(ifp,"AX25");
  157.         ifp->ioctl = kiss_ioctl;
  158.         ifp->raw = kiss_raw;
  159.         ifp->show = slip_status;
  160.         ifp->port = 0;            /* G1EMM */
  161.         if(ifp->hwaddr == NULLCHAR)
  162.             ifp->hwaddr = mallocw(AXALEN);
  163.         memcpy(ifp->hwaddr,Mycall,AXALEN);
  164.         ifp->xdev = xdev;
  165.  
  166.         sp->iface = ifp;
  167.         sp->send = asy_send;
  168.         sp->kiss[ifp->port] = ifp;    /* G1EMM */
  169.         sp->get = get_asy;
  170.         sp->type = CL_KISS;
  171.         trigchar = FR_END;
  172.         ifp->rxproc = newproc( ifn = if_name( ifp, " rx" ),
  173.             256,asy_rx,xdev,NULL,NULL,0);
  174.         free(ifn);
  175.     } else
  176. #endif
  177. #ifdef    NRS
  178.     if(stricmp(argv[3],"NRS") == 0) {
  179.         /* Set up a net/rom serial iface */
  180.         for(xdev = 0;xdev < SLIP_MAX;xdev++){
  181.             np = &Nrs[xdev];
  182.             if(np->iface == NULLIF)
  183.                 break;
  184.         }
  185.         if(xdev >= SLIP_MAX) {
  186.             tprintf("Too many nrs devices\n");
  187.             free(ifp->name);
  188.             free((char *)ifp);
  189.             return -1;
  190.         }
  191.         /* no call supplied? */
  192.         setencap(ifp,"AX25");
  193.         ifp->ioctl = asy_ioctl;
  194.         ifp->raw = nrs_raw;
  195. /*        ifp->show = nrs_status; */
  196.         ifp->hwaddr = mallocw(AXALEN);
  197.         memcpy(ifp->hwaddr,Mycall,AXALEN);
  198.         ifp->xdev = xdev;
  199.         np->iface = ifp;
  200.         np->send = asy_send;
  201.         np->get = get_asy;
  202.         trigchar = ETX;
  203.         ifp->rxproc = newproc( ifn = if_name( ifp, " nrs" ),
  204.             256,nrs_recv,xdev,NULL,NULL,0);
  205.         free(ifn);
  206.     } else
  207. #endif
  208. #ifdef    PPP
  209.     if(stricmp(argv[3],"PPP") == 0) {
  210.         /* Setup for Point-to-Point Protocol */
  211.         trigchar = HDLC_FLAG;
  212.         monitor = TRUE;
  213.         setencap(ifp,"PPP");
  214.         ifp->ioctl = asy_ioctl;
  215.         ifp->flags = FALSE;
  216.         /* Initialize parameters for various PPP phases/protocols */
  217.         if (ppp_init(ifp) != 0) {
  218.             tprintf("Cannot allocate PPP control block\n");
  219.             free(ifp->name);
  220.             free((char *)ifp);
  221.             return -1;
  222.         }
  223.     } else
  224. #endif /* PPP */
  225.     {
  226.         tprintf("Mode %s unknown for interface %s\n",
  227.             argv[3],argv[4]);
  228.         free(ifp->name);
  229.         free((char *)ifp);
  230.         return -1;
  231.     }
  232.  
  233.     /* Link in the interface */
  234.     ifp->next = Ifaces;
  235.     Ifaces = ifp;
  236. #ifdef UNIX
  237.     /* *ix version can fail (e.g. "device locked"). Detach if it does. */
  238.     if (asy_init(dev,ifp,argv[1],argv[2],(int16)atol(argv[5]),
  239.              trigchar,monitor,(int16)atol(argv[7]),
  240.              force,triglevel) == -1)
  241.         if_detach(ifp);
  242. #else
  243.     asy_init(dev,ifp,argv[1],argv[2],(int16)atol(argv[5]),
  244.         trigchar,monitor,(int16)atol(argv[7]),force,triglevel);
  245. #endif
  246.     return 0;
  247. }
  248.  
  249. static int
  250. asy_detach(ifp)
  251. struct iface *ifp;
  252. {
  253.     asy_stop(ifp);
  254.  
  255. #ifdef    SLIP
  256.     if(stricmp(ifp->iftype->name,"SLIP") == 0) {
  257.         Slip[ifp->xdev].iface = NULLIF;
  258. #ifdef VJCOMPRESS
  259.         slhc_free( Slip[ifp->xdev].slcomp );
  260.         Slip[ifp->xdev].slcomp = NULL;
  261. #endif    /* VJCOMPRESS */
  262.     } else
  263. #endif
  264. #ifdef    AX25
  265.     if(stricmp(ifp->iftype->name,"AX25") == 0
  266.      && Slip[ifp->xdev].iface == ifp ) {
  267.         Slip[ifp->xdev].iface = NULLIF;
  268.     } else
  269. #endif
  270. #ifdef    NRS
  271.     if(stricmp(ifp->iftype->name,"AX25") == 0
  272.      && Nrs[ifp->xdev].iface == ifp ) {
  273.         Nrs[ifp->xdev].iface = NULLIF;
  274.     } else
  275. #endif
  276. #ifdef    PPP
  277.     if(stricmp(ifp->iftype->name,"PPP") == 0) {
  278.         ppp_free(ifp);
  279.     } else
  280. #endif
  281.     {
  282.         tprintf("invalid type %s for interface %s\n",
  283.             ifp->iftype->name, ifp->name);
  284.         free(ifp->name);
  285.         free(ifp);
  286.         return -1;
  287.     }
  288.     return 0;
  289. }
  290.  
  291. /* Execute user comm command */
  292. int
  293. doasycomm(argc,argv,p)
  294. int argc;
  295. char *argv[];
  296. void *p;
  297. {
  298.     register struct iface *ifp;
  299.     register struct asy *ap;
  300.     int dev;
  301.     struct mbuf *bp;
  302.     
  303.     if((ifp = if_lookup(argv[1])) == NULLIF){
  304.         tprintf(Badinterface,argv[1]);
  305.         return 1;
  306.     }
  307.     for(dev=0,ap = Asy;dev < ASY_MAX;dev++,ap++)
  308.         if(ap->iface == ifp)
  309.             break;
  310.     if(dev == ASY_MAX){
  311.         tprintf("Interface %s not asy port\n",argv[1]);
  312.         return 1;
  313.     }
  314.  
  315.     bp = pushdown(NULLBUF,(int16)strlen(argv[2]) + 2 );
  316.     strcpy(bp->data,argv[2]);
  317.     strcat(bp->data,"\r");
  318.     bp->cnt = strlen(argv[2]) + 1;
  319.     asy_send(dev,bp);
  320.     return 0;
  321. }
  322.  
  323.